package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.PromiseStyleMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise

////////////////////
// Google Cloud Messaging
////////////////////
/**
 * Use `Browser.gcm` to enable apps and extensions to send and receive messages through Firebase Cloud Messaging (FCM).
 *
 * Permissions: "gcm"
 */
interface Gcm {
    // The maximum size (in bytes) of all key/value pairs in a message. default is 4096
    val MAX_MESSAGE_SIZE: Int

    // Registers the application with FCM. The registration ID will be returned by the callback.
    // If register is called again with the same list of senderIds,
    // the same registration ID will be returned.
    // @return {callback.registrationId} A registration ID assigned to the application by the FCM.
    @PromiseStyleMinVersion(116)
    fun register(
        // A list of server IDs that are allowed to send messages to the application.
        // It should contain at least one and no more than 100 sender IDs.
        senderIds: List<String>,
        callback: Value1Function<String>? = null
    ): Promise<String>

    // Sends a message according to its contents.
    // @return {callback.messageId} The ID of the message that the callback was issued for.
    @PromiseStyleMinVersion(116)
    fun send(
        message: OutgoingMessage,
        callback: Value1Function<String>?
    ): Promise<String>

    // Unregisters the application from FCM.
    @PromiseStyleMinVersion(116)
    fun unregister(
        callback: VoidFunction? = null
    ): Promise<Void>

    // Fired when a message is received through FCM.
    val onMessage: Events.Event<Value1Function<ReplyMessage>>

    // Fired when a FCM server had to delete messages sent by an app server to the application.
    // See Lifetime of a message for details on handling this event.
    val onMessagesDeleted: Events.Event<VoidFunction>

    // Fired when it was not possible to send a message to the FCM server.
    val onSendError: Events.Event<Value1Function<GcmError>>

    data class OutgoingMessage(
        // Message data to send to the server. Case-insensitive goog. and google,
        // as well as case-sensitive collapse_key are disallowed as key prefixes.
        // Sum of all key/value pairs should not exceed gcm.MAX_MESSAGE_SIZE.
        var data: Any,
        // The ID of the server to send the message to as assigned by Google API Console.
        var destinationId: String,
        // The ID of the message. It must be unique for each message in scope of the applications.
        // See the Cloud Messaging documentation for advice for picking and handling an ID.
        var messageId: String,
        // Time-to-live of the message in seconds.
        // If it is not possible to send the message within that time, an onSendError event will be raised.
        // A time-to-live of 0 indicates that the message should be sent immediately or fail if it's not possible.
        // The default value of time-to-live is 86,400 seconds (1 day) and the maximum value is 2,419,200 seconds (28 days).
        var timeToLive: Number?,
    )

    data class ReplyMessage(
        // The collapse key of a message. See the Non-collapsible and collapsible messages for details.
        var collapseKey: String?,
        // The message data.
        var data: Any,
        // The sender who issued the message.
        var from: String?,
    )

    data class GcmError(
        // Additional details related to the error, when available.
        var details: Any,
        // The error message describing the problem.
        var errorMessage: String,
        // The ID of the message with this error, if error is related to a specific message.
        var messageId: String?
    )
}